思路:
不采用GLKBaseEffect,使用编译链接自定义的着色器(shader)。用简单的glsl语言来实现顶点、片元着色器,并对图形进行简单的变换。
1.创建图层
2.创建上下文
3.清空缓存区
4.设置RenderBuffer
5.设置FrameBuffer
6.开始绘制
代码实现
1 | -(void)layoutSubviews |
设置图层
头文件引入:1
属性创建:1
2
3
4
5
6
7
8
9//在iOS和tvOS上绘制OpenGL ES内容的图层,继承与CALayer
@property(nonatomic,strong)CAEAGLLayer *myEagLayer;
@property(nonatomic,strong)EAGLContext *myContext;
@property(nonatomic,assign)GLuint myColorRenderBuffer;
@property(nonatomic,assign)GLuint myColorFrameBuffer;
@property(nonatomic,assign)GLuint myPrograme;
设置图层:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37//1.设置图层
-(void)setupLayer
{
//给图层开辟空间
/*
重写layerClass,将CCView返回的图层从CALayer替换成CAEAGLLayer
*/
self.myEagLayer = (CAEAGLLayer *)self.layer;
//设置放大倍数
[self setContentScaleFactor:[[UIScreen mainScreen]scale]];
//CALayer 默认是透明的,必须将它设为不透明才能将其可见。
self.myEagLayer.opaque = YES;
//设置描述属性,这里设置不维持渲染内容以及颜色格式为RGBA8
/*
kEAGLDrawablePropertyRetainedBacking 表示绘图表面显示后,是否保留其内容。这个key的值,是一个通过NSNumber包装的bool值。如果是false,则显示内容后不能依赖于相同的内容,ture表示显示后内容不变。一般只有在需要内容保存不变的情况下,才建议设置使用,因为会导致性能降低、内存使用量增减。一般设置为flase.
kEAGLDrawablePropertyColorFormat
可绘制表面的内部颜色缓存区格式,这个key对应的值是一个NSString指定特定颜色缓存区对象。默认是kEAGLColorFormatRGBA8;
kEAGLColorFormatRGBA8:32位RGBA的颜色,4*8=32位
kEAGLColorFormatRGB565:16位RGB的颜色,
kEAGLColorFormatSRGBA8:sRGB代表了标准的红、绿、蓝,即CRT显示器、LCD显示器、投影机、打印机以及其他设备中色彩再现所使用的三个基本色素。sRGB的色彩空间基于独立的色彩坐标,可以使色彩在不同的设备使用传输中对应于同一个色彩坐标体系,而不受这些设备各自具有的不同色彩坐标的影响。
*/
self.myEagLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:false],kEAGLDrawablePropertyRetainedBacking,kEAGLColorFormatRGBA8,kEAGLDrawablePropertyColorFormat,nil];
}
+(Class)layerClass
{
return [CAEAGLLayer class];
}
设置上下文
1 | //2.设置上下文 |
清空缓存区
1 | //3.清空缓存区 |
设置RenderBuffer
1 | //4.设置RenderBuffer |
设置FrameBuffer
1 | //5.设置FrameBuffer |
开始绘制
1 | //6.开始绘制 |
加载shader 与 链接shader
1 |
|
设置纹理
1 | //设置纹理 |
GLSL程序编写
OpenGL ES的可编程管线中的顶点着色器和片元着色器需要开发者自行编写, 对应的语言为GLSL(OpenGL Shading Language), 其中顶点着色器处理传入的顶点坐标, 片元着色器将顶点坐标进行光栅化处理, 显示出图形
顶点着色器程序: shaderVertex.fsh
1 | attribute vec4 position;// 处理顶点数据 |
片元着色器程序: shaderFrgment.fsh
1 | varying lowp vec2 varyTextCoord; |
顶点着色器调用次数与顶点数量相关, 片元着色器调用与像素多少相关, 所以片元着色器的调用次数比较多
运行结果
可以看到图形是反的, 这是因为纹理本身是倒置的, 下面将讲解解决图形倒置的三种方法
解决图形倒置的方法
1. 设置图形旋转角度
可以看到上面的图形除了倒置之外, 还有一些倾斜, 是因为我们在代码中设置了图形的旋转角度为10度, 那么我们将这个参数调整为180度, 即可将图形倒置回来
另外, 若不想让图形旋转, 则需要注释掉这部分代码, 并注释顶点着色器中关于rotateMatrix的部分
2. 调整纹理坐标
纹理的坐标是倒置的, 那么我们调整纹理坐标, 也可以将图形倒置回来